function [F, g, G] = Watson(x)
% WATSON - 输出Watson函数在x点的函数值，与梯度值。
% Call：
% [F, g, G] = Watson(x)
%    [F, g] = Watson(x)
%       [F] = Watson(x)
% 输入参数：
% x     ：给定的点，函数的n由x长度确定。
% 输出参数：
% F     ：函数值
% g     ：梯度值，不要求不计算
% G     ：Hessen矩阵，不要求不计算
    [stop, n] = check(x);
    if stop, error('x must be a real valued vector'), end
    if n <2, error('x must have length more than 1'),end
    x = x(:);
    r(30) = x(1);
    r(31) = x(2)-x(1)^2-1;
    for i = 1:29,
        t = i/29;
        cache(i)=0;
        for k = 1:n,
            cache(i) = cache(i)+x(k)*t^(k-1);
        end
        r(i) = 0;
        for k = 2:n,
            r(i) = r(i)+(k-1)*x(k)*t^(k-2);
        end
        r(i) = r(i) - (cache(i))^2-1;
    end
    
    F = sum(r.^2);
    
    if nargout>1,
        pr = zeros(n,31);
        g  = zeros(n,1);
        pr(1,30)=1;
        pr(1,31)=-2*x(1);
        pr(2,31)=1;
        for i = 1:29,
            t = i/29;
            for k = 1:n,
                pr(k,i)=(k-1)*t^(k-2)-2*cache(i)*t^(k-1);
            end
            g = g + 2*pr(:,i)*r(i);
        end
        g = g+2*pr(:,30)*r(30);
        g = g+2*pr(:,31)*r(31);
    end
    
    if nargout>2,
        G = zeros(n, n);
        Hr = zeros(n,n,31);
        Hr(1,1,31) =-2;
        for i = 1: 29,
            t = i/29;
            for l = 1:n,
                for k = 1:n,
                    Hr(l,k,i)= -2*t^(l+k-2);
                end
            end
        end
        for i = 1:31,
            G = G+Hr(:,:,i)*r(i);
            for l = 1:n,
                for k = 1:n,
                    G(l,k) = G(l,k) + pr(l,i) * pr(k,i);
                end
            end
        end
        G = 2*G;
    end
end
%============  Auxiliary functions  ========================

function [err,n] = check(x)
% CHECK - check x
%   
    err = 0; sx = size(x); n = max(sx);
    if  (min(sx) ~= 1) | ~isreal(x) | any(isnan(x(:))) | isinf(norm(x(:))) 
        err = -1; 
    end    
end
